import java.util.*;

/**
 * @class PrimeNumbersFinder 
 * 
 * This program implements Task 1 from the "Java Basics" chapter of "Java SE" training:
 * finds prime numbers which are smaller or equal to the inputted from keyboard integer number.
 *
 * @version 1.0
 * @date 2013-06-18
 * @author Inna Ianko
*/
public class PrimeNumbersFinder {
		 
	public static final String PROGRAM_DESCRIPTION =
			"This program will find prime numbers which are smaller or equal\n to positive integer number entered.";		
	public static final String LINES_SEPARATOR = 
			"----------------------------------------------------------------";	
	public static final String ENTER_DATA_MESSAGE =
			"Please enter positive integer number bigger then '1'";	
	public static final String DATA_ENTERED_NOT_CORRECT_MESSAGE = 
			"You have entered invalid data.";				
	public static final String RESULT_HEADER_MESSAGE =
			"The next prime numbers where found:";	
	public static final String NEXT_LINE = "\n";
	public static final String SPACE = " ";	
	public static final String COLON = ":";		
	public static final int FIRST_PRIME_NUMBER = 2;
	public static final int REMINDER_FOR_NOT_PRIME_NUMBERS = 0;
			
	public static void main (String[] args) {
			
		printDescription(PROGRAM_DESCRIPTION);	
		
		int numberToManipulate = getInputPositiveNumber();		
		int[] calculatedPrimeNumbers = findPrimeNumbers(numberToManipulate);
		
		printPrimesNumbers(calculatedPrimeNumbers);
	}
 
	public static int getInputPositiveNumber() {
			
		boolean dataEnteredIsValid;	
        String enteredText;	
				 	       		 
		do {		
			enteredText = askUserForInput();			
			dataEnteredIsValid = validateDataInput(enteredText);				
			printInvalidInputStateIfTrue(dataEnteredIsValid);
			
		} while (!dataEnteredIsValid);
				
		return Integer.parseInt(enteredText);
	}	
	
	public static String askUserForInput() {
			
		Scanner input = new Scanner(System.in);
		
		System.out.println(ENTER_DATA_MESSAGE + COLON);	
		return input.nextLine();	
	}
	
	public static boolean validateDataInput(String entredText) {
			
		try	{								
			return 
					(Integer.parseInt(entredText) >= FIRST_PRIME_NUMBER); 	
		} catch (NumberFormatException exception) {	
			return false;	
		}					
	}
	
	public static void printInvalidInputStateIfTrue(boolean dataEnteredIsValid) {
												  
		if (!dataEnteredIsValid) {						
			System.out.println(NEXT_LINE 
					+ DATA_ENTERED_NOT_CORRECT_MESSAGE + NEXT_LINE);
		}									  
	}
		
	public static int[] findPrimeNumbers(int numberToManipulate) {
		  						
		int[] result = {FIRST_PRIME_NUMBER}; 
		
	    if (numberToManipulate > FIRST_PRIME_NUMBER) {
		
			boolean applicantNumberIsPrime; 	
			
			for (int applicantForPrimeNumber = (FIRST_PRIME_NUMBER + 1);
					applicantForPrimeNumber <= numberToManipulate; applicantForPrimeNumber++) {	
					
				applicantNumberIsPrime = checkNumberIsPrime(applicantForPrimeNumber);					
				result = addNumberToArrayIfPrime(result, applicantForPrimeNumber, applicantNumberIsPrime);								
			}						
		}		
		return result;										
	}
	
	public static boolean checkNumberIsPrime(int applicantForPrimeNumber) {
		
		boolean applicantNumberIsPrime = true;
		
		for (int divisor = FIRST_PRIME_NUMBER;
				divisor < applicantForPrimeNumber; divisor++) {
					
			applicantNumberIsPrime = 
					(applicantForPrimeNumber % divisor) != REMINDER_FOR_NOT_PRIME_NUMBERS;
					
			if (!applicantNumberIsPrime) {					   
				return false;	
			}						
		}	
		return true;
	}
	
	public static int[] addNumberToArrayIfPrime(int[] arrayToEnlarge, int numberToAdd, boolean numberIsPrime) {
		
		if (numberIsPrime) {
			int lengthOfArray = arrayToEnlarge.length;
			int indexToAdd = lengthOfArray;
		
			++lengthOfArray;	
			arrayToEnlarge = Arrays.copyOf(arrayToEnlarge, lengthOfArray);					
			arrayToEnlarge[indexToAdd] = numberToAdd;	
		}
		return arrayToEnlarge;
	}
	
	public static void printPrimesNumbers(int[] numbersToPrint) {
		
		System.out.print(NEXT_LINE + RESULT_HEADER_MESSAGE 
				+ NEXT_LINE + NEXT_LINE);	
		
		for (int index = 0; index < numbersToPrint.length; index++) {
			System.out.print(numbersToPrint[index] + SPACE);
		}
		
		System.out.print(NEXT_LINE);	
	}
		
	public static void printDescription(String description) {
	
		System.out.println(NEXT_LINE + LINES_SEPARATOR);
		System.out.println(NEXT_LINE + SPACE + description);
		System.out.println(LINES_SEPARATOR);
	}
}